#ifndef GAMEENGINE_GRAPHICS_LIGHTING_MATERIAL_H
#define GAMEENGINE_GRAPHICS_LIGHTING_MATERIAL_H

#include <GameEngine/Graphics/graphics_settings.h>

#include <GameEngine/Core/Color/color_rgb.h>
#include <GameEngine/Graphics/Texture/texture2d.h>

#include <QtCore/QFlags>

#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//! Implements material properties
/*!
 *  Material properties define how the material being drawn will catch the lights
 *  that illuminate it.
 *
 *  The parameters of the material are applied only if they are activated on the
 *  Material object. This limits the number of OpenGL calls - but unfortunately, all
 *  parameters of the material have to be stored, which makes the Material object
 *  inefficient in memory. One way to work around this issue would be to store
 *  dynamic data.
 */
class _Graphics_decl Material {

public:
	//! Enumerates which parameters are enabled on the material
	enum MaterialParameter {
		//! Define the ambient color of the material
		AmbientMaterial   = 1,
		//! Define the diffuse color of the material
		DiffuseMaterial   = 2,
		//! Define the specular color of the material
		SpecularMaterial  = 4,
		//! Define the emission color of the material
		EmissionMaterial  = 8,
		//! Define the shininess of the material
		ShininessMaterial = 16,
		//! Define the color of the material
		ColorMaterial     = 32,
		//! Define the transparency of the material
		AlphaMaterial     = 64,
		//! Define the textured flag of the material
		TexturedMaterial  = 128
	};

	Q_DECLARE_FLAGS(MaterialParameters,MaterialParameter)

public:
	Material();
	Material(const Material& rhs);
	virtual ~Material();
	Material& operator=(const Material& rhs);

	const ColorRGBA& ambient_color() const;
	void set_ambient_color(const ColorRGBA& ambient);
	const ColorRGBA& diffuse_color() const;
	void set_diffuse_color(const ColorRGBA& diffuse);
	const ColorRGBA& specular_color() const;
	void set_specular_color(const ColorRGBA& specular);
	const ColorRGBA& emission_color() const;
	void set_emission_color(const ColorRGBA& emission);

	float shininess() const;
	void set_shininess(float shininess);

	const ColorRGB& color() const;
	void set_color(const ColorRGB& color_rgba);
	float alpha() const;
	void set_alpha(float alpha);

	Texture2d* texture() const;
	void set_texture(const Texture2d* texture);

	const GEString& name() const;
	GEString& name();

	bool active_parameter(MaterialParameter parameter) const;
	bool set_active_parameter(MaterialParameter parameter, bool enable=true);

	void apply_material() const;
	void remove_material() const;

protected:
	//! Parameters activated on the material
	MaterialParameters parameters_;

	//! Ambient color of the material
	ColorRGBA acolor_;
	//! Diffuse color of the material
	ColorRGBA dcolor_;
	//! Specular color of the material
	ColorRGBA scolor_;
	//! Emission color of the material
	ColorRGBA ecolor_;

	//! Shininess of the material
	float shininess_;

	//! Color of the material
	ColorRGB color_;
	//! Transparency of the material
	float alpha_;

	//! Texture associated to the material
	Texture2d* texture_;

	//! Name of the material
	GEString name_;
};


//========================================================


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
